package com.oswift.gpm.service.impl;

import java.util.ArrayList;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.servlet.ModelAndView;

import com.oswift.gpm.dao.GroupDao;
import com.oswift.gpm.dao.OpsInfoDao;
import com.oswift.gpm.dao.RoleDao;
import com.oswift.gpm.dao.SystemDao;
import com.oswift.gpm.entity.GroupBean;
import com.oswift.gpm.entity.GroupROpsBean;
import com.oswift.gpm.entity.GroupRRoleBean;
import com.oswift.gpm.entity.OpsInfoBean;
import com.oswift.gpm.entity.RoleBean;
import com.oswift.gpm.entity.SystemModuleBean;
import com.oswift.gpm.service.IGroupService;
import com.oswift.gpm.utils.Constant;
import com.oswift.gpm.utils.PageCode;
import com.oswift.utils.cache.ResourceManager;
import com.oswift.utils.common.StringUtil;
import com.oswift.utils.exception.ErrorCode;
import com.oswift.utils.exception.PlatException;

/**
 *
 * 权限管理分组的业务处理类
 *
 * @author zhuou
 * @version C03 Oct 27, 2012
 * @since OSwift GPM V1.0
 */
public class GroupServiceImpl implements IGroupService
{
    /**
     * 日志实例
     */
    private static Logger log = LoggerFactory.getLogger(GroupServiceImpl.class);

    /**
     * SystemDao spring注入实例
     */
    private SystemDao systemDao;

    /**
     * SystemDao spring注入实例
     */
    private GroupDao groupDao;

    /**
     * OpsInfoDao spring注入实例
     */
    private OpsInfoDao opsInfoDao;

    /**
     * RoleDao spring注入实例
     */
    private RoleDao roleDao;

    /**
     *
     * 加载页面groupList.jsp所需要的页面数据
     *
     * @author zhuou
     * @param pageName
     *            groupList.jsp
     * @return ModelAndView
     * @throws PlatException
     *             平台公共异常
     */
    public ModelAndView loadGroupList(String pageName) throws PlatException
    {
        ModelAndView mv = null;
        try
        {
            List<SystemModuleBean> list = systemDao.getSysList();

            mv = new ModelAndView(pageName);
            mv.addObject("sysList", list);
        }
        catch (Exception e)
        {
            throw new PlatException(ErrorCode.COMMON_DB_ERROR, e);
        }
        return mv;
    }

    /**
     *
     * 加载Group新增页面，获取页面需要的数据
     *
     * @author zhuou
     * @param sysId
     *            系统Id
     * @return ModelAndView
     * @throws PlatException
     *             平台公共异常
     */
    public ModelAndView loadGroup(String sysId, String groupId)
        throws PlatException
    {
        ModelAndView mv = new ModelAndView(Constant.PageName.GROUP);

        try
        {
            // 获取系统操作list
            // List<OpsInfoBean> opsList = opsInfoDao.selectList(sysId);

            // 获取系统角色list
            List<RoleBean> roleList = roleDao.getRolesBySysId(sysId);

            if (!StringUtil.isEmpty(groupId))
            {
                List<GroupRRoleBean> groupRRoleBean = groupDao
                        .getGroupRRole(groupId);
                if (null != roleList && !roleList.isEmpty()
                        && null != groupRRoleBean && !groupRRoleBean.isEmpty())
                {
                    for (RoleBean item1 : roleList)
                    {
                        for (GroupRRoleBean item2 : groupRRoleBean)
                        {
                            if (item1.getRoleId() == item2.getRoleId())
                            {
                                item1.setChecked(true);
                            }
                        }
                    }
                }
            }

            // mv.addObject("opsList", opsList);
            mv.addObject("roleList", roleList);
        }
        catch (Exception e)
        {
            throw new PlatException(ErrorCode.COMMON_DB_ERROR, e);
        }

        return mv;
    }

    /**
     *
     * 添加一条分组记录
     *
     * @author zhuou
     * @param group
     *            Group
     * @param roleIds
     *            角色ID字符串，以“,”分隔
     * @param opsIds
     *            操作Id字符串，以“,”分隔
     * @return boolean
     */
    @Transactional(rollbackFor = PlatException.class)
    public boolean addGroup(GroupBean group, String roleIds, String opsIds)
        throws PlatException
    {
        int rows = groupDao.add(group);
        if (rows <= 0)
        {
            return false;
        }

        List<GroupROpsBean> groupROpsBean = null;
        List<GroupRRoleBean> groupRRoleBean = null;

        // 判断是否要继承父节点的权限
        if (group.getInherit())
        {
            groupROpsBean = groupDao.getGroupROps(String.valueOf(group
                    .getParentId()));
            if (null != groupROpsBean && groupROpsBean.size() > 0)
            {
                for (GroupROpsBean item : groupROpsBean)
                {
                    // 将成功插入的groupid赋值
                    item.setGroupId(group.getGroupId());
                    // 将是否是继承的权限标志置为true
                    item.setInherit(true);
                }
            }

            groupRRoleBean = groupDao.getGroupRRole(String.valueOf(group
                    .getParentId()));
            if (null != groupRRoleBean && groupRRoleBean.size() > 0)
            {
                for (GroupRRoleBean item : groupRRoleBean)
                {
                    // 将成功插入的groupid赋值
                    item.setGroupId(group.getGroupId());
                    // 将是否是继承的权限标志置为true
                    item.setInherit(true);
                }
            }
        }

        if (!StringUtil.isEmpty(opsIds))
        {
            if (null == groupROpsBean)
            {
                groupROpsBean = new ArrayList<GroupROpsBean>();
            }
            String[] arrayId = opsIds.split(",");
            for (String s : arrayId)
            {
                GroupROpsBean itemBean = new GroupROpsBean();
                itemBean.setGroupId(group.getGroupId());
                itemBean.setOpsId(Integer.valueOf(s));
                itemBean.setInherit(false);
                groupROpsBean.add(itemBean);
            }
        }

        if (!StringUtil.isEmpty(roleIds))
        {
            if (null == groupRRoleBean)
            {
                groupRRoleBean = new ArrayList<GroupRRoleBean>();
            }
            String[] arrayId = roleIds.split(",");
            for (String s : arrayId)
            {
                GroupRRoleBean itemBean = new GroupRRoleBean();
                itemBean.setGroupId(group.getGroupId());
                itemBean.setRoleId(Integer.valueOf(s));
                itemBean.setInherit(false);
                groupRRoleBean.add(itemBean);
            }
        }

        if (null != groupROpsBean && groupROpsBean.size() > 0)
        {
            rows = groupDao.addGroupROps(groupROpsBean);
            if (rows <= 0)
            {
                log.error("insert into t_gpm_r_opsgroup fail.groupId="
                        + group.getGroupId());
                throw new PlatException(ErrorCode.COMMON_DB_ERROR);
            }
        }

        if (null != groupRRoleBean && groupRRoleBean.size() > 0)
        {
            rows = groupDao.addGroupRRole(groupRRoleBean);
            if (rows <= 0)
            {
                log.error("insert into t_gpm_r_rolegroup fail.groupId="
                        + group.getGroupId());
                throw new PlatException(ErrorCode.COMMON_DB_ERROR);
            }
        }
        return true;
    }

    /**
     *
     * 根据sysId获取组/部门的信息
     *
     * @author zhuou
     * @param sysId
     *            系统ID
     * @return List
     * @throws PlatException
     *             公共异常
     */
    public List<GroupBean> getGroupList(String sysId) throws PlatException
    {
        try
        {
            return groupDao.selectList(sysId);
        }
        catch (Exception e)
        {
            throw new PlatException(ErrorCode.COMMON_DB_ERROR, e);
        }
    }

    /**
     *
     * 根据groupId查询组详情
     *
     * @author zhuou
     * @param groupId
     *            组id
     * @return GroupBean
     */
    public GroupBean getDetailById(String groupId) throws PlatException
    {
        try
        {
            GroupBean bean = groupDao.selectOne(groupId);
            if (null == bean)
            {
                throw new PlatException(PageCode.GET_GROUPDETAIL_FAIL);
            }

            // 获取父节点名称
            if (bean.getParentId() != Constant.PARENT_ID)
            {
                GroupBean parentBean = groupDao.selectOne(bean.getParentId());
                if (null == parentBean)
                {
                    throw new PlatException(PageCode.GET_GROUPDETAIL_FAIL);
                }
                bean.setParentName(parentBean.getGroupName());
            }
            else
            {
                bean.setParentName(ResourceManager
                        .getValue(PageCode.NO_PARENT_NAME));
            }

            return bean;
        }
        catch (Exception e)
        {
            throw new PlatException(ErrorCode.COMMON_DB_ERROR, e);
        }
    }

    /**
     *
     * 根据组ID获取组拥有的角色
     *
     * @author zhuou
     * @param groupId
     *            组id
     * @return List<RoleBean>
     */
    public List<RoleBean> getRolesByGroupId(String groupId)
        throws PlatException
    {
        try
        {
            return groupDao.getRolesByGroupId(groupId);
        }
        catch (Exception e)
        {
            throw new PlatException(ErrorCode.COMMON_DB_ERROR, e);
        }
    }

    /**
     *
     * 根据组ID获取组拥有的操作权限
     *
     * @author zhuou
     * @param groupId
     *            组ID
     * @return List<OpsInfoBean>
     */
    public List<OpsInfoBean> getOpsByGroupId(String groupId)
        throws PlatException
    {
        try
        {
            return groupDao.getOpsByGroupId(groupId);
        }
        catch (Exception e)
        {
            throw new PlatException(ErrorCode.COMMON_DB_ERROR, e);
        }
    }

    /**
     *
     * 修改组记录
     *
     * @author zhuou
     * @param group
     *            Group
     * @param roleIds
     *            角色ID字符串，以“,”分隔
     * @param opsIds
     *            操作Id字符串，以“,”分隔
     * @return boolean
     */
    @Transactional(rollbackFor = PlatException.class)
    public boolean updateGroup(GroupBean group, String roleIds, String opsIds)
        throws PlatException
    {
        GroupBean bean = groupDao.selectOne(group.getGroupId());

        // 判断是否已经被删除
        if (null == bean)
        {
            throw new PlatException(PageCode.GROUP_ALREADY_DELETE);
        }

        // 根据组id删除组和操作关联表数据
        int rows1 = groupDao.delGroupROpsbyGroupId(String.valueOf(group
                .getGroupId()));

        // 根据组id删除组和角色关联表数据
        int rows2 = groupDao.delGroupRRolebyGroupId(String.valueOf(group
                .getGroupId()));

        // 因为t_gpm_r_rolegroup或者t_gpm_r_opsgroup其中之一必定有数据，所以如果返回都为0则认为没有删除成功
        if (rows1 <= 0 && rows2 <= 0)
        {
            throw new PlatException(PageCode.UPDATE_GROUP_FAIL);
        }

        int rows = groupDao.update(group);
        if (rows <= 0)
        {
            throw new PlatException(PageCode.UPDATE_GROUP_FAIL);
        }

        List<GroupROpsBean> groupROpsBean = null;
        List<GroupRRoleBean> groupRRoleBean = null;

        // 判断是否要继承父节点的权限
        if (group.getInherit())
        {
            groupROpsBean = groupDao.getGroupROps(String.valueOf(group
                    .getParentId()));
            if (null != groupROpsBean && groupROpsBean.size() > 0)
            {
                for (GroupROpsBean item : groupROpsBean)
                {
                    // 将成功插入的groupid赋值
                    item.setGroupId(group.getGroupId());
                    // 将是否是继承的权限标志置为true
                    item.setInherit(true);
                }
            }

            groupRRoleBean = groupDao.getGroupRRole(String.valueOf(group
                    .getParentId()));
            if (null != groupRRoleBean && groupRRoleBean.size() > 0)
            {
                for (GroupRRoleBean item : groupRRoleBean)
                {
                    // 将成功插入的groupid赋值
                    item.setGroupId(group.getGroupId());
                    // 将是否是继承的权限标志置为true
                    item.setInherit(true);
                }
            }
        }

        if (!StringUtil.isEmpty(opsIds))
        {
            if (null == groupROpsBean)
            {
                groupROpsBean = new ArrayList<GroupROpsBean>();
            }
            String[] arrayId = opsIds.split(",");
            for (String s : arrayId)
            {
                GroupROpsBean itemBean = new GroupROpsBean();
                itemBean.setGroupId(group.getGroupId());
                itemBean.setOpsId(Integer.valueOf(s));
                itemBean.setInherit(false);
                groupROpsBean.add(itemBean);
            }
        }

        if (!StringUtil.isEmpty(roleIds))
        {
            if (null == groupRRoleBean)
            {
                groupRRoleBean = new ArrayList<GroupRRoleBean>();
            }
            String[] arrayId = roleIds.split(",");
            for (String s : arrayId)
            {
                GroupRRoleBean itemBean = new GroupRRoleBean();
                itemBean.setGroupId(group.getGroupId());
                itemBean.setRoleId(Integer.valueOf(s));
                itemBean.setInherit(false);
                groupRRoleBean.add(itemBean);
            }
        }

        if (null != groupROpsBean && groupROpsBean.size() > 0)
        {
            rows = groupDao.addGroupROps(groupROpsBean);
            if (rows <= 0)
            {
                log.error("insert into t_gpm_r_opsgroup fail.groupId="
                        + group.getGroupId());
                throw new PlatException(PageCode.UPDATE_GROUP_FAIL);
            }
        }

        if (null != groupRRoleBean && groupRRoleBean.size() > 0)
        {
            rows = groupDao.addGroupRRole(groupRRoleBean);
            if (rows <= 0)
            {
                log.error("insert into t_gpm_r_rolegroup fail.groupId="
                        + group.getGroupId());
                throw new PlatException(PageCode.UPDATE_GROUP_FAIL);
            }
        }
        return true;
    }

    /**
     *
     * 删除组/部门信息
     *
     * @author zhuou
     * @param groupId
     *            组ID
     * @return boolean
     * @throws PlatException
     *             公共异常
     */
    @Transactional(rollbackFor = PlatException.class)
    public boolean delGroup(String groupId) throws PlatException
    {
        GroupBean bean = groupDao.selectOne(groupId);
        if (null == bean)
        {
            throw new PlatException(PageCode.OPSINFO_DELETED, ResourceManager
                    .getValue(PageCode.OPSINFO_DELETED));
        }

        // 根据组id删除组和操作关联表数据
        groupDao.delGroupROpsbyGroupId(groupId);

        // 根据组id删除组和角色关联表数据
        groupDao.delGroupRRolebyGroupId(groupId);

        // 根据组id删除组和用户关联表数据
        groupDao.delGroupRUserbyGroupId(groupId);

        // 修改此组下的所有子节点的parentID
        GroupBean groupInfo = new GroupBean();
        groupInfo.setParentId(bean.getParentId());
        groupInfo.setGroupId(bean.getGroupId());
        groupDao.updateChildParentId(groupInfo);

        boolean isSuccess = groupDao.delete(groupId) > 0 ? true : false;

        return isSuccess;
    }

    public void setSystemDao(SystemDao systemDao)
    {
        this.systemDao = systemDao;
    }

    public SystemDao getSystemDao()
    {
        return systemDao;
    }

    public GroupDao getGroupDao()
    {
        return groupDao;
    }

    public void setGroupDao(GroupDao groupDao)
    {
        this.groupDao = groupDao;
    }

    public OpsInfoDao getOpsInfoDao()
    {
        return opsInfoDao;
    }

    public void setOpsInfoDao(OpsInfoDao opsInfoDao)
    {
        this.opsInfoDao = opsInfoDao;
    }

    public RoleDao getRoleDao()
    {
        return roleDao;
    }

    public void setRoleDao(RoleDao roleDao)
    {
        this.roleDao = roleDao;
    }
}
